/**
 * vue2 reactive 基本实现原理
 */

let obj = {
  name: "ck",
  age: 19,
  info: {
    address: "sh",
  },
  arr: ["zs", "ls"],
};

function update(key, value) {
  console.log(`当前${key}发生更新,更新后数据为${value}`);
}

const oldArrayProperty = Array.prototype;
const arrayProperty = Object.create(oldArrayProperty);

["push", "pop", "shift", "unshift"].forEach((methodName) => {
  arrayProperty[methodName] = function () {
    // 调用更新函数
    update(methodName);
    oldArrayProperty[methodName].call(this, ...arguments);
  };
});

function defineActivite(target, key, value) {
  // 防止，属性值也是个引用数据类型
  observer(target[key]);
  Object.defineProperty(target, key, {
    get() {
      console.log("get value");
      return value;
    },
    set(newValue) {
      // 防止重新赋值的也是个引用数据类型
      observer(newValue);
      console.log("set value");
      update(key, newValue);
      value = newValue;
    },
  });
}
function observer(target) {
  if (typeof target !== "object" || target === null) return target;

  // 如果是数组，需要去重写数组
  if (Array.isArray(target)) {
    target.__proto__ = arrayProperty;
  }
  Object.keys(target).forEach((key) => {
    defineActivite(target, key, target[key]);
  });
}

observer(obj);

obj.name = 10;
obj.info.address = "sh1";
obj.info = { score: 100 };
obj.info.score = 120;

obj.arr.push("w5");
